package com.example.ssrbac.controller;

import com.example.ssrbac.entity.User;
import com.example.ssrbac.security.JwtTokenUtil;
import com.example.ssrbac.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;
import org.springframework.http.HttpStatus;
import javax.servlet.http.HttpServletRequest;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 认证控制器
 * 
 * 该控制器负责处理用户认证相关的请求，包括：
 * 1. 用户登录
 * 2. 用户登出
 * 3. 强制用户登出
 * 
 * @author Your Name
 * @version 1.0
 */
@RestController
@RequestMapping("/api/auth")
public class AuthController {
    private static final Logger logger = LoggerFactory.getLogger(AuthController.class);

    /**
     * 认证管理器，用于处理认证请求
     */
    @Autowired
    private AuthenticationManager authenticationManager;

    /**
     * JWT工具类，用于生成和验证token
     */
    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    /**
     * 用户服务，用于处理用户相关的业务逻辑
     */
    @Autowired
    private UserService userService;

    /**
     * Redis模板，用于管理token缓存
     */
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 处理用户登录请求
     * 
     * @param loginRequest 登录请求参数，包含用户名和密码
     * @return 包含JWT token的响应
     */
    @PostMapping("/login")
    public ResponseEntity<?> login(@RequestBody Map<String, String> loginRequest) {
        String username = loginRequest.get("username");
        logger.info("Processing login request for user: {}", username);

        try {
            Authentication authentication = authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(
                            username,
                            loginRequest.get("password")
                    )
            );

            SecurityContextHolder.getContext().setAuthentication(authentication);
            
            String jwt = jwtTokenUtil.generateToken((org.springframework.security.core.userdetails.User) authentication.getPrincipal());
            logger.debug("JWT token generated for user: {}", username);

            String oldToken = (String) redisTemplate.opsForValue().get("user:" + username + ":token");
            if (oldToken != null) {
                logger.debug("Found existing token for user: {}, adding to blacklist", username);
                redisTemplate.opsForValue().set("blacklist:" + oldToken, "1", 24, TimeUnit.HOURS);
            }
            redisTemplate.opsForValue().set("user:" + username + ":token", jwt, 24, TimeUnit.HOURS);
            logger.debug("New token stored in Redis for user: {}", username);

            Map<String, Object> response = new HashMap<>();
            response.put("token", jwt);
            logger.info("Login successful for user: {}", username);
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            logger.error("Login failed for user: {}, error: {}", username, e.getMessage());
            throw e;
        }
    }

    /**
     * 处理用户登出请求
     * 
     * @param token 用户的JWT token
     * @return 空响应
     */
    @PostMapping("/logout")
    public ResponseEntity<?> logout(@RequestHeader("Authorization") String token) {
        logger.info("Processing logout request");
        if (token != null && token.startsWith("Bearer ")) {
            token = token.substring(7);
            userService.logout(token);
            logger.info("Logout successful");
        } else {
            logger.warn("Invalid token format in logout request");
        }
        return ResponseEntity.ok().build();
    }

    /**
     * 处理强制用户登出请求
     * 
     * @param username 要强制登出的用户名
     * @return 空响应
     */
    @PostMapping("/force-logout/{username}")
    public ResponseEntity<?> forceLogout(@PathVariable String username) {
        logger.info("Processing force logout request for user: {}", username);
        userService.forceLogout(username);
        logger.info("Force logout successful for user: {}", username);
        return ResponseEntity.ok().build();
    }

    /**
     * 检查token是否有效
     * 
     * @param request HTTP请求
     * @return 如果token有效返回200，否则返回401
     */
    @GetMapping("/check-token")
    public ResponseEntity<?> checkToken(HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        if (token != null && token.startsWith("Bearer ")) {
            token = token.substring(7);
            try {
                String username = jwtTokenUtil.getUsernameFromToken(token);
                Boolean isBlacklisted = redisTemplate.hasKey("blacklist:" + token);
                if (Boolean.TRUE.equals(isBlacklisted)) {
                    logger.warn("Token在黑名单中: {}", token);
                    return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
                }
                return ResponseEntity.ok().build();
            } catch (Exception e) {
                logger.error("Token验证失败", e);
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
            }
        }
        return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
    }
} 